package org.lora.webframework.dashboard;

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.lora.core.annotation.Action;
import org.lora.mvc.annotation.RequestPath;
import org.lora.mvc.annotation.ResponseJSON;
import org.lora.mvc.entity.ViewData;
import org.lora.webframework.common.WebframeBaseAction;
import org.lora.webframework.util.MathUtil;

/**
 * <p>
 * Title:DashboardAction
 * </p>
 * <p>
 * Desription:工作台Action
 * </p>
 * Create Time:2016年7月7日 下午3:52:53
 * 
 * @author Bladnir@outlook.com
 *         <p>
 *         History:
 *         </p>
 *         2016年7月7日 Bladnir Create</br>
 */

@Action
@RequestPath(path = "/webframework/dashboard")
public class DashboardAction extends WebframeBaseAction {

	/**
	 * 打开主页面
	 * 
	 * @return
	 */
	@RequestPath(path = "/showIndex")
	public ViewData showIndex() {
		return new ViewData("/jsp/common/index.jsp");
	}

	/**
	 * 打开工作台页面
	 * 
	 * @return
	 */
	@RequestPath(path = "/showMainPage")
	public ViewData showMainPage() {
		return new ViewData("/jsp/webframework/dashboard/dashboard.jsp");
	}

	/**
	 * 获取所有图表需要的数据
	 * 
	 * @return
	 */
	@RequestPath(path = "/getSplineData")
	@ResponseJSON
	public Map<String, Object> getSplineData() {
		Map<String, Object> resultMap = new HashMap<>();

		// 堆内存整体使用量
		MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
		
		resultMap.put("heapMemoryUsageUsed", heapMemoryUsage.getUsed() / 1048576);
		resultMap.put("heapMemoryUsageMax", heapMemoryUsage.getMax() / 1048576);
		resultMap.put("nowTime", System.currentTimeMillis());

		//内存区信息
		List<Map<String, Object>> memoryList = getMemoryPoolInfo();
		resultMap.put("memoryList", memoryList);

		//内存回收信息
		List<Map<String, Object>> gcInfoList = getGcInfoList();
		resultMap.put("gcInfoList", gcInfoList);
		
		//根据状态统计线程数量和总数
		Map<String,Integer> threadNumberMap = getThreadNumber();
		resultMap.put("threadNumberMap", threadNumberMap);

		return resultMap;
	}
	
	/**
	 * 根据状态统计线程数量和总数
	 * 
	 * @return
	 */
	private Map<String,Integer> getThreadNumber(){
		
		Map<String,Integer> resultMap = new HashMap<>();
		
		ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
		ThreadInfo[] thiArray = threadMXBean.dumpAllThreads(true, true);
		
		int totalNumber = thiArray.length;
		resultMap.put("totalNumber", totalNumber);
		
		for(ThreadInfo ti : thiArray){
			
			String state = ti.getThreadState().toString();
			
			if(resultMap.containsKey(state)){
				Integer count = resultMap.get(state);
				count = count+1;
				resultMap.put(state, count);
			}else{
				resultMap.put(state, 1);
			}
			
		}
		
		return resultMap;
		
	}
	
	/**
	 * 垃圾回收信息
	 * 
	 * @return
	 */
	private List<Map<String, Object>> getGcInfoList(){
		List<Map<String, Object>> gcInfoList = new ArrayList<>();
		
		List<GarbageCollectorMXBean> garbageCollectorMXBeanList = ManagementFactory.getGarbageCollectorMXBeans();
		
		for (GarbageCollectorMXBean gcBean : garbageCollectorMXBeanList) {
			Map<String, Object> map = new HashMap<>();

			map.put("Name", gcBean.getName());
			map.put("CollectionCount", Long.toString(gcBean.getCollectionCount()));
			map.put("CollectionTime", Long.toString(gcBean.getCollectionTime() / 1000));

			long averageTime = 0l;
			if (gcBean.getCollectionCount() != 0) {
				averageTime = gcBean.getCollectionTime() / gcBean.getCollectionCount();
			}

			map.put("averageTime", averageTime);

			gcInfoList.add(map);
		}
		
		return gcInfoList;
	}

	/**
	 * 获取内存池信息
	 * 
	 * @return
	 */
	private List<Map<String, Object>> getMemoryPoolInfo() {

		List<Map<String, Object>> resultList = new ArrayList<>();

		List<MemoryPoolMXBean> list = ManagementFactory.getMemoryPoolMXBeans();

		for (MemoryPoolMXBean pool : list) {

			MemoryUsage mu = pool.getUsage();

			if (pool.getType().equals(MemoryType.NON_HEAP)) {
				continue;
			}
			
			Map<String, Object> dataMap = new HashMap<>();
			String poolName;

			if (pool.getName().toLowerCase().indexOf("old") != -1) {
				poolName = "old";
			} else if (pool.getName().toLowerCase().indexOf("eden") != -1) {
				poolName = "eden";
			} else if (pool.getName().toLowerCase().indexOf("survivor") != -1) {
				poolName = "survivor";
			} else {
				poolName = pool.getName();
			}
			dataMap.put("poolName", poolName);
			dataMap.put("usePercent", MathUtil.getPercentNumber(Long.toString(mu.getUsed()), Long.toString(mu.getMax()), 2));
			resultList.add(dataMap);

		}

		return resultList;

	}

}
